# 高阶组件(HOC):最经典的组件逻辑复用方式
# 什么是高阶组件
高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。——React 官方
高阶函数的概念:接收函数作为输入,或者输出另一个函数的一类函数,就是高阶函数。
相应的,高阶组件指的就是参数为组件,返回值为新组件的函数。没错,高阶组件本质上是一个函数。下面是一个简单的高阶组件示例:
const withProps = (WrappedComponent) => {
const targetComponent = (props) => (
<div className="wrapper-container">
<WrappedComponent {...props} />
</div>
);
return targetComponent;
};
在这段代码中,withProps 就是一个高阶组件。
# 高阶组件是如何实现逻辑复用的?
现在我们考虑这样一种情况:我有一个名为 checkUserAccess 的方法,这个方法专门用来校验用户的身份是否合法,若不合法,那么一部分组件就要根据这个不合法的身份调整自身的展示逻辑(比如查看个人信息界面需要提示“请校验身份”等)。
假如说页面中的 A、B、C、D、E 五个组件都需要甄别用户身份是否合法,那么这五个组件在理论上都需要先请求一遍 checkUserAccess 这个接口。但一个一个对组件进行修改未免太麻烦了,我们期望对“获取 checkUserAccess 接口信息,并通知到对应组件”这层逻辑进行复用,这时候就可以请出高阶组件来帮忙了。
我们可以像下面代码这样在高阶组件中定义这层通用的逻辑:
// 假设 checkUserAccess 已经在 utils 文件中被封装为了一段独立的逻辑
import checkUserAccess from './utils
// 用高阶组件包裹目标组件
const withCheckAccess = (WrappedComponent) => {
// 这部分是通用的逻辑:判断用户身份是否合法
const isAccessible = checkUserAccess()
// 将 isAccessible(是否合法) 这个信息传递给目标组件
const targetComponent = (props) => (
<div className="wrapper-container">
<WrappedComponent {...props} isAccessible={isAccessible} />
</div>
);
return targetComponent;
};
这样当我们需要为某个组件复用这层请求逻辑的时候,只需要直接用 withCheckAccess 包裹这个组件就可以了。以 A 组件为例,假设 A 组件的原始版本为 AComponent,那么包裹它的形式就是下面代码这样:
const EnhancedAComponent = withCheckAccess(Acomponent);
通过简单地对高阶组件 withCheckAccess 进行引入,EnhancedAComponent 轻松具备了校验用户合法性的能力。这样一来,即便再多出 5 个组件想要引入 checkUserAccess,我们也不会怂——毕竟包裹五个组件和重写五段逻辑的工作量是没法相提并论的
高阶组件不仅能够帮助我们简化逻辑的引入过程,还可以帮助我们规避掉逻辑变更带来的烦琐的修改步骤:假如这段 checkUserAccess 的逻辑是散落在 A、B、C、D、E 这五个组件之中的,那么一旦 checkUserAccess 的判定规则需要修改,我们就得需要去修改五段代码;但现在,checkUserAccess 被抽离进了一个独立的高阶组件里,我们在高阶组件中的一次修改,将在所有被它处理过的组件中生效。
